package com.zpz.framework.zpzoauth.common.result;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.zpz.framework.zpzoauth.common.encrypt.DefaultCrypto;
import com.zpz.framework.zpzoauth.common.encrypt.SignUtil;
import com.zpz.framework.zpzoauth.pojo.po.OauthClientDetails;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class CommonResult {
    private static Logger log = LoggerFactory.getLogger(GatewayResult.class);

    public static Map<String, Object> getResponseBody(String apicode, Enum<?> status, String data, String error, String en, String sign, OauthClientDetails oauthClientDetails) {
        ZpzOauthResultMsg<Object> re = ZpzOauthResultMsg.customResultStatus(status);
        boolean decrypt = false;
        boolean signFlag = false;
        String signStr = null;
        String nonceStr = null;
        String timestamp = null;
        try {
            decrypt = (StringUtils.isNotBlank(en) && en.equals("1")) ? true : false;
            signFlag = (StringUtils.isNotBlank(sign)&&sign.equals("1")) ? true : false;
            signStr = null;
            nonceStr = null;
            timestamp = null;
            if (StringUtils.isNotBlank(data)) {
                // 解析响应报文
                Map<String, Object> map = null;// 签名用的响应参数的数据体（要签名必须是map）
                Object datare = null;//响应体参数的数据体
                ZpzOauthResultMsg re1 = null;
                try {
                    re1 = JSON.parseObject(data, ZpzOauthResultMsg.class);// 响应体统一格式严格遵守code/message/data
                    if (re1 != null) {
                        datare = re1.getData();
                        Object code = re1.getCode();
                        if (code != null && !code.toString().equals("")) {
                            re.setCode(Integer.parseInt(code.toString()));
                        }
                        Object message = re1.getMessage();
                        if (message != null && !message.toString().equals("")) {
                            re.setMessage(message.toString());
                        }
                        if (datare != null){
                            re.setData(re1.getData());
                            // 加密
                            if (decrypt) {
                                if (datare != null && !datare.toString().equals("")) {
                                    try {
                                        //加密原始响应数据体（data）
                                        String s = JSON.toJSONStringWithDateFormat(datare, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect);
                                        data = s;
                                        data = Base64.encodeBase64String(data.getBytes("UTF-8"));
                                        data = DefaultCrypto.encodDataPublicKey(data, oauthClientDetails.getPublicKey());
                                        log.info("业务请求[" + apicode + "]：:：：:::::::::::加密数据：：：：：" + data);
                                        re.setData(data);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        error = e.getMessage();
                                        re = ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10019,e.getMessage());
                                        decrypt = false;
                                        signFlag = false;
                                    }
                                }
                            }
                            // 签名
                            if (signFlag) {
                                String s = JSON.toJSONStringWithDateFormat(datare, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect);
                                map = (Map<String, Object>) JSON.parse(s);//将原始响应体数据转成map格式
                                if (map != null) {
                                    Map<String, String> mapre = coverMap(map);
                                    try {
                                        timestamp = System.currentTimeMillis() + "";//精确到毫秒的时间戳//
                                        nonceStr = SignUtil.generateNonceStr();//随机字符串
                                        signStr = DefaultCrypto.sign(mapre, nonceStr, timestamp, oauthClientDetails.getSignKey()/*CommonConstant.PRIVATE_KEY*/);
                                    } catch (Exception e) {
                                        error = e.getMessage();
                                        re = ZpzOauthResultMsg.customResultStatus(ZpzOauthResultStatus.GATE_WAY_10021,e.getMessage());
                                        decrypt = false;
                                        signFlag = false;
                                    }
                                } else {
                                    if (StringUtils.isNotBlank(s)){
                                        error = "业务API响应数据格式错误，非key-value不能进行数据签名";
                                        re = ZpzOauthResultMsg.error(error);
                                        decrypt = false;
                                        signFlag = false;
                                    }
                                }
                            }
                        } else {
                            decrypt = false;
                            signFlag = false;
                        }
                    } else {
                        decrypt = false;
                        signFlag = false;
                        error="业务响应体为空";
                        re = ZpzOauthResultMsg.error(error);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    error = e.getMessage();
                    re = ZpzOauthResultMsg.error(error);
                    decrypt = false;
                    signFlag = false;
                }
            } else {
                if (re.getCode() != 0){
                    decrypt = false;
                    signFlag = false;
                    error=error;
                    re = ZpzOauthResultMsg.error(error);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            decrypt = false;
            signFlag = false;
            error=e.getMessage();
            re = ZpzOauthResultMsg.error(error);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("code", re.getCode());
        map.put("message", StringUtils.isNotBlank(error)?error:re.getMessage());
        map.put("errorDesc", error);
        map.put("sign", signStr);
        map.put("noncestr", nonceStr);
        map.put("timestamp", timestamp);
        map.put("de", decrypt);
        map.put("vsg", signFlag);
        map.put("data", re.getData());
        return map;
    }

    public static Map<String, String> coverMap(Map<String, Object> map) {
        Map<String, String> resmap = new HashMap<>();
        for (String m : map.keySet()) {
            Object param = map.get(m);
            String str = "";
            if (param != null && !param.toString().equals("")) {
                if (param instanceof Integer) {
                    str = param.toString();
                } else if (param instanceof String) {
                    str = param.toString();
                } else if (param instanceof Double) {
                    str = param.toString();
                } else if (param instanceof Float) {
                    str = param.toString();
                } else if (param instanceof BigDecimal) {
                    str = param.toString();
                } else if (param instanceof Long) {
                    str = param.toString();
                } else if (param instanceof Boolean) {
                    str = param.toString();
                } else if (param instanceof Date) {
                    str = JSONObject.toJSONStringWithDateFormat(param, "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
                } else {
                    str = JSON.toJSONString(param, SerializerFeature.DisableCircularReferenceDetect);
                }
            } else {
                str = "";
            }
            resmap.put(m, str);
        }
        return resmap;
    }

    public static void main(String[] args) {
        try {
            String timestamp = System.currentTimeMillis() + "";//精确到毫秒的时间戳//
            String nonceStr = SignUtil.generateNonceStr();//随机字符串
            Map<String,String> json = new HashMap<>();
            json.put("grant_type", "password");
            json.put("password", "123456");
            json.put("username", "15010526670");
            json.put("scope", "all");
            json.put("auth_type", "mobile_pwd");
            String sign = DefaultCrypto.sign(json, nonceStr, timestamp, "b292c22796c156468e2f839adace8f83");
            System.out.println(sign);
            System.out.println(timestamp);
            System.out.println(nonceStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
